package cn.fl.customer.service.impl;

import cmm.comm.facade.framework.api.ISysCdMapApiService;
import cmm.comm.facade.framework.api.ISysDictionaryApiService;
import cmm.comm.facade.framework.condition.SysCdMapDQueryCondition;
import cmm.comm.facade.framework.dto.SysCdMapDDTO;
import cmm.comm.facade.framework.dto.SysDictionaryDTO;
import cmm.mid.core.framework.dto.DataResultDTO;
import cmm.mid.core.framework.page.KeyValueVO;
import cmm.mid.core.framework.page.Pager;
import cmm.user.facade.system.api.ISysOrgApiService;
import cmm.user.facade.system.dto.SysUsrDTO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.constant.BaseExceptionConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.cmm.cache.framework.utils.PropertiesCacheUtils;
import cn.fl.capital.condition.CapOverdueCompleteQC;
import cn.fl.capital.constant.CapitalConstant;
import cn.fl.capital.dto.CapFundVfDtlDTO;
import cn.fl.capital.service.ICapOverdueInfoApiService;
import cn.fl.commons.result.ResponseData;
import cn.fl.customer.service.ICstBscInfoService;
import cn.fl.customer.service.IPrjBillApplyService;
import cn.fl.customer.service.IPrjBillBscInfoService;
import cn.fl.customer.transform.PrjBillApplyRecVOTransform;
import cn.fl.customer.transform.PrjBillApplyVOTransform;
import cn.fl.customer.transform.PrjBillBscInfoVOTransform;
import cn.fl.customer.utils.XmlUtils;
import cn.fl.customer.vo.CstBscInfoVO;
import cn.fl.customer.vo.PrjBillApplyRecVO;
import cn.fl.customer.vo.PrjBillApplyVO;
import cn.fl.customer.vo.PrjBillBscInfoVO;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.framework.constant.DictionaryConstant;
import cn.fl.project.api.IProjectQueryApiService;
import cn.fl.project.condition.PrjBscInfoQueryCondition;
import cn.fl.project.condition.PrjPrdPaySchMQueryCondition;
import cn.fl.project.constant.PrjPrdPaySchMConstant;
import cn.fl.project.dto.PrjBscInfoDTO;
import cn.fl.project.dto.PrjPrdPaySchMDTO;
import cn.fl.project.service.IPrjPrdPaySchMApiService;
import cn.fl.project.service.IProjectApiService;
import cn.fl.system.service.ISysUsrService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import fl.constant.facade.framework.constant.SystemConstant;
import fl.customer.facade.invoice.api.ICustInvoiceApiService;
import fl.customer.facade.invoice.api.IInvoiceApiService;
import fl.customer.facade.invoice.condition.PrjBillApplyRecQueryCondition;
import fl.customer.facade.invoice.condition.PrjBillBscInfoQueryCondition;
import fl.customer.facade.invoice.condition.SearchValidInvoiceQueryCondition;
import fl.customer.facade.invoice.constant.PrjBillApplyConstant;
import fl.customer.facade.invoice.dto.*;
import fl.flow.facade.flow.constant.FlowConstant;
import fl.flow.facade.flow.dto.FlowStartParamsDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.Charset;
import java.util.*;

/**
 * @Description: 票据申请表表 客户端服务层接口实现
 * @Description: 业务层方法名称前缀：新增：add* 删除：remove* 修改：modify* 查询对象：select* get* 批量：batch* 查询集合：search*
 */
@Service
public class PrjBillApplyServiceImpl implements IPrjBillApplyService {

	/**
	 * 日志
	 */
	private static final Logger logger = LoggerFactory.getLogger(IPrjBillApplyService.class);
	
	@Autowired
	private ICustInvoiceApiService custInvoiceApiService;
	
	@Autowired
	private ISysDictionaryApiService sysDictionaryApiService;
	
	/**
	 * 组织架构服务
	 */
	@Autowired
	private ISysOrgApiService sysOrgApiService;
	
	@Autowired
	private IPrjPrdPaySchMApiService prjPrdPaySchMApiService;
	
	/**
	 * 逾期信息服务
	 */
	@Autowired
	private ICapOverdueInfoApiService capOverdueInfoApiService;
	
	/**
	 * 项目基础API服务
	 */
	@Autowired
	private IProjectApiService projectApiService;
	
	/**
	 * 代码映射表服务
	 */
	@Autowired
	private ISysCdMapApiService sysCdMapApiService;

	@Autowired
    private ICstBscInfoService cstBscInfoService;

    @Autowired
    private IProjectQueryApiService projectQueryApiService;

    @Autowired
    private IInvoiceApiService invoiceApiService;

	@Override
	public PrjBillApplyVO selectById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "selectById", "主键参数不能为空!", CurrentThreadContext.getCurrentUserName());
			return null;
		}
		PrjBillApplyDTO dto = custInvoiceApiService.selectPrjBillApplyById(id);
		
		//获取项目所属事业部名称-项目经理所属事业部就是项目所属事业部
		if(null != dto && StringUtils.isNotEmpty(dto.getBuOrgCd())){
			try {
				String buOrgCdNm = this.sysOrgApiService.selectSysOrgNmByOrgCd(dto.getBuOrgCd(), CurrentThreadContext.getFlServiceSysCd());
				dto.setBuOrgCdNm(buOrgCdNm);
			} catch (Exception e) {
				BaseLogUtils.error(logger, "selectById", "获取事业部名称失败!" + e.getMessage(), CurrentThreadContext.getCurrentUserName());
				dto.setBuOrgCdNm("");
			}
		}
		
		if(null != dto){
		    if (PrjBillApplyConstant.BILL_WAY_CD_1.equals(dto.getBillWayCd())) {
                PrjBillBscInfoQueryCondition prjBillBscInfoQueryCondition = new PrjBillBscInfoQueryCondition();
                prjBillBscInfoQueryCondition.setApplyId(dto.getId());
                List<PrjBillBscInfoDTO> prjBillBscInfoDTOS = this.custInvoiceApiService.searchBillBscInfoList(prjBillBscInfoQueryCondition);
                if (CollectionUtils.isNotEmpty(prjBillBscInfoDTOS)) {
                    dto.setDownloadUrl(prjBillBscInfoDTOS.get(0).getDownloadUrl());
                    dto.setPaidUpAmt(prjBillBscInfoDTOS.get(0).getBillAmt());
                    dto.setSerialNum(prjBillBscInfoDTOS.get(0).getSerialNo());
                }
            }
            List<String> codeGrpCdList = new ArrayList<>();
			codeGrpCdList.add(DictionaryConstant.CODE_SYS_YES_NO_CD);
			codeGrpCdList.add(DictionaryConstant.CODE_GRP_CST_NP_BK_CD);
			// 新加客户类型
            codeGrpCdList.add(DictionaryConstant.CODE_GRP_CST_TYP_CD);
			Map<String, Map<String,String>> dicMap = this.sysDictionaryApiService.searchMultiGroupToMap(CurrentThreadContext.getFlServiceSysCd(), CurrentThreadContext.getCurrentOrgCd(), codeGrpCdList);
			if(CollectionUtils.isMapNotEmpty(dicMap)){
				Map<String,String> yesNoMap = dicMap.get(DictionaryConstant.CODE_SYS_YES_NO_CD);
				if(CollectionUtils.isMapEmpty(yesNoMap)){
					yesNoMap = new HashMap<>();
				}
				Map<String,String> bkCdMap = dicMap.get(DictionaryConstant.CODE_GRP_CST_NP_BK_CD);
				if(CollectionUtils.isMapEmpty(bkCdMap)){
					bkCdMap = new HashMap<>();
				}
                Map<String,String> cstTypCdMap = dicMap.get(DictionaryConstant.CODE_GRP_CST_TYP_CD);
                if(CollectionUtils.isMapEmpty(cstTypCdMap)){
                    cstTypCdMap = new HashMap<>();
                }
				
				if(StringUtils.isNotEmpty(dto.getIsPreInv())){
					dto.setIsPreInvNm(yesNoMap.get(String.valueOf(dto.getIsPreInv())));
				}
				
				if(StringUtils.isNotEmpty(dto.getInvBkCd())){
					dto.setInvBkCdNm(bkCdMap.get(dto.getInvBkCd()));
				}

                CstBscInfoVO cstBscInfoVO = this.cstBscInfoService.selectById(dto.getCstId());
				if (null != cstBscInfoVO && StringUtils.isNotEmpty(cstBscInfoVO.getCstTypCd())) {
				    dto.setCstTypNm(cstTypCdMap.get(cstBscInfoVO.getCstTypCd()));
                }
			}

		}
		
		return PrjBillApplyVOTransform.toVO(dto);
	}

	@Override
	public Long add(PrjBillApplyVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "add", "新增对象不能为空!", CurrentThreadContext.getCurrentUserName());
			return null;
		}
		return this.custInvoiceApiService.addPrjBillApply(PrjBillApplyVOTransform.toDTO(entity));
	}
	
	@Override
	public Long addClearPay(PrjBillApplyVO entity) throws BaseException {
		if(null == entity){
			BaseLogUtils.info(logger, "addClearPay", "新增对象不能为空!", CurrentThreadContext.getCurrentUserName());
			return null;
		}
		String sysCd = CurrentThreadContext.getFlServiceSysCd();
		String orgCd = CurrentThreadContext.getCurrentOrgCd();
		String buOrgCd = CurrentThreadContext.getCurrentBuOrgCd();
		return this.custInvoiceApiService.addPrjBillApplyForClearPay(PrjBillApplyVOTransform.toDTO(entity), sysCd, orgCd, buOrgCd);
	}

	@Override
	public boolean removeById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "removeById", "删除主键参数不能为空!", CurrentThreadContext.getCurrentUserName());
			return false;
		}
		return this.custInvoiceApiService.removeBillApplyById(id);
	}
	
	/**
     * 删除
     * @param ids
     * @return
     */
    public boolean removeByIds(List<Long> ids)throws BaseException{
    	if(CollectionUtils.isEmpty(ids)){
    		BaseLogUtils.info(logger, "removeByIds", "删除主键参数集合不能为空!", CurrentThreadContext.getCurrentUserName());
			return false;
		};
		return false;
    }

	@Override
	public boolean modify(PrjBillApplyVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "modify", "修改对象参数不能为空!", CurrentThreadContext.getCurrentUserName());
			return false;
		}
		return this.custInvoiceApiService.modifyBillApply(PrjBillApplyVOTransform.toDTO(entity));
	}

	@SuppressWarnings("unchecked")
	@Override
	public Pager searchListPage(Pager page) throws BaseException{
		if(null == page)page = new Pager();
		Pager newPage = this.custInvoiceApiService.searchBillApplyListPage(page);
		List<PrjBillApplyDTO> list = (List<PrjBillApplyDTO>)newPage.getResultList();
		newPage.setResultList(PrjBillApplyVOTransform.toVOList(list));
		return newPage;
	}

	@Override
	public List<PrjBillApplyRecVO> searchApplyList(PrjBillApplyRecQueryCondition condition) throws BaseException {
		//获取当前登录人组织架构下所有项目ID, 和 客户ID作为主要查询条件查询数据
		List<Long> prjIdList = new ArrayList<>();
		try {
			//如果condition.getPrjIdList()为空说明前面未指定项目ID去查询
			if(CollectionUtils.isEmpty(condition.getPrjIdList())){
				PrjBscInfoQueryCondition prjBscInfoQueryCondition = new PrjBscInfoQueryCondition();
				prjBscInfoQueryCondition.setUsrId(CurrentThreadContext.getCurrentUserId());
				prjBscInfoQueryCondition.setSysCd(CurrentThreadContext.getCurrentSysCd());
				prjBscInfoQueryCondition.setCstId(condition.getCstId());
				prjBscInfoQueryCondition.setOrgCd(CurrentThreadContext.getCurrentOrgCd());
				List<PrjBscInfoDTO> prjList = this.projectApiService.searchList(prjBscInfoQueryCondition, CurrentThreadContext.getCurrentSysCd(), CurrentThreadContext.getCurrentOrgCd());
				if(CollectionUtils.isNotEmpty(prjList)){
					for (PrjBscInfoDTO prjBscInfoDTO : prjList) {
						prjIdList.add(prjBscInfoDTO.getId());
					}
				}
			}else{
				prjIdList.addAll(condition.getPrjIdList());
			}
		} catch (BaseException e) {
			BaseLogUtils.info(logger, "searchApplyList", "获取项目接口失败！" + e.getMessage());
		} catch (Exception e) {
			BaseLogUtils.error(logger, "searchApplyList", "获取项目接口失败！" + e.getMessage());
		}
		
		BaseLogUtils.info(logger, "searchApplyList", "B项目ID:" + JSON.toJSONString(prjIdList));
		CollectionUtils.removeDuplicate(prjIdList);
		//项目没有则返回空
		List<PrjBillApplyRecDTO> list = null;
		if(CollectionUtils.isEmpty(prjIdList)){
			BaseLogUtils.error(logger, "searchApplyList", "未获取到项目ID集合！");
			return PrjBillApplyRecVOTransform.toVOList(list);
		}
		
		//这种情况是指定了项目ID去查询数据
		//if(CollectionUtils.isEmpty(condition.getPrjIdList())){
			condition.setPrjIdList(prjIdList);
		//}
		//如果要有支付表ID则也要过滤
		Long paySchMId = condition.getPaySchMId();
		if(StringUtils.isNotEmpty(paySchMId)){
			condition.setPaySchMId(paySchMId);
		}
        BaseLogUtils.info(logger, "searchApplyList", "查询开票申请时所能开发票的列表数据!" + JSON.toJSONString(condition));
        list = this.custInvoiceApiService.searchApplyList(condition);
        BaseLogUtils.info(logger, "searchApplyList", "查询开票申请时所能开发票的列表数据!" + JSON.toJSONString(list));
        //获取数据字典
		Map<String,String> feeTypCdMap = null;
		Map<String,String> capFlowCdMap = null;
		Map<String, String> billTypeMap = null;
		try {
			Map<String, Map<String,String>> cdMap = null;
			List<String> codeGrpCdList = new ArrayList<>();
			codeGrpCdList.add(DictionaryConstant.CODE_PRJ_QUAT_FEE_ALL_TYP_CD);
			String capFlowCdKey = PropertiesCacheUtils.getProperty(fl.constant.facade.framework.constant.DictionaryConstant.CODE_CAP_FLOW_CD);
			codeGrpCdList.add(capFlowCdKey);
			codeGrpCdList.add(DictionaryConstant.CODE_PRJ_BILL_TYP_CD);
			cdMap = this.sysDictionaryApiService.searchMultiGroupToMap(condition.getSysCd(), condition.getOrgCd(), codeGrpCdList);
			if(CollectionUtils.isMapEmpty(cdMap)){
				cdMap = new HashMap<>();
			}
			feeTypCdMap = cdMap.get(DictionaryConstant.CODE_PRJ_QUAT_FEE_ALL_TYP_CD);
			capFlowCdMap = cdMap.get(capFlowCdKey);
			billTypeMap = cdMap.get(DictionaryConstant.CODE_PRJ_BILL_TYP_CD);
			if(CollectionUtils.isMapEmpty(billTypeMap)){
				billTypeMap = new HashMap<>();
			}
		} catch (Exception e) {
			BaseLogUtils.info(logger, "searchApplyList", "获取数据字典项失败!" + JSON.toJSONString(condition));
		}finally {
			if(CollectionUtils.isMapEmpty(feeTypCdMap)){
				feeTypCdMap = new HashMap<>();
			}
			
			if(CollectionUtils.isMapEmpty(capFlowCdMap)){
				capFlowCdMap = new HashMap<>();
			}
			
			if(CollectionUtils.isMapEmpty(billTypeMap)){
				billTypeMap = new HashMap<>();
			}
		}
		
		Map<String, String> feeTypMap = new HashMap<>();
		try {
			String mTypCd = PropertiesCacheUtils.getProperty(fl.constant.facade.framework.constant.SysCdMapConstant.M_TYP_CD_FEE_TYP_CD);
			String sysCd = CurrentThreadContext.getFlServiceSysCd();
			SysCdMapDQueryCondition sysCdMapDQueryCondition = new SysCdMapDQueryCondition();
			sysCdMapDQueryCondition.setmTypCd(mTypCd);
			sysCdMapDQueryCondition.setSysCd(sysCd);
			sysCdMapDQueryCondition.setOrgCd(CurrentThreadContext.getCurrentOrgCd());
			List<SysCdMapDDTO> feeTypList = this.sysCdMapApiService.searchSysCdMapDWithTargetList(sysCdMapDQueryCondition);
			if(CollectionUtils.isNotEmpty(feeTypList)){
				for (SysCdMapDDTO sysCdMapDDTO : feeTypList) {
					feeTypMap.put(sysCdMapDDTO.getSCode(), sysCdMapDDTO.getTCode());
				}
			}
		} catch (Exception e) {
			BaseLogUtils.error(logger, "searchApplyList", "获取代码映射表失败." + e.getMessage(), CurrentThreadContext.getCurrentUserName());
		}finally {
			if(CollectionUtils.isMapEmpty(feeTypMap)){
				feeTypMap = new HashMap<>();
			}
		}
		
		if(CollectionUtils.isNotEmpty(list)){
			//特殊处理数据
			List<Long> paySchIdList = new ArrayList<>();
			for (PrjBillApplyRecDTO prjBillApplyRecDTO : list) {
				if(!paySchIdList.contains(prjBillApplyRecDTO.getPaySchId())){
					paySchIdList.add(prjBillApplyRecDTO.getPaySchId());
				}
				//只需要查询大于第0期作为查询条件
				Integer payPd = prjBillApplyRecDTO.getPayPd();
				//需要把费用项的名字标记为第*期*(第1期利息) 第0期除外
				String actualName = prjBillApplyRecDTO.getFeeTypCdNm();
				if(null != payPd && payPd.intValue() > 0){
					prjBillApplyRecDTO.setFeeTypCdNm("第" + payPd + "期" + actualName);
				}
				prjBillApplyRecDTO.setCapFlowNm(capFlowCdMap.get(prjBillApplyRecDTO.getCapFlow()));
			}
			CollectionUtils.removeDuplicate(paySchIdList);
		}
		
		
		//==================1、要查询出来所有支付表租赁物总价-并且这个要过滤是否在申请表中已经存在=========================
		PrjPrdPaySchMQueryCondition prjPrdPaySchMQueryCondition = new PrjPrdPaySchMQueryCondition();
		prjPrdPaySchMQueryCondition.setCstId(condition.getCstId());
		prjPrdPaySchMQueryCondition.setPrjIdList(prjIdList);
		prjPrdPaySchMQueryCondition.setFeeTypCd(DictionaryConstant.CODE_PRJ_QUAT_FEE_TYP_CD_S06);
		prjPrdPaySchMQueryCondition.setBillStsCd(DictionaryConstant.CODE_PRJ_BILL_STS_CD_1);
		//如果查询条件中支付表ID不能与空则赋值给支付表ID
		if(StringUtils.isNotEmpty(paySchMId)){
			prjPrdPaySchMQueryCondition.setId(paySchMId);
		}
		//未提交 、审核中
		List<String> audStsCdList = new ArrayList<>();
		audStsCdList.add(FlowConstant.FLOW_CHECK_STATE_NON);
		audStsCdList.add(FlowConstant.FLOW_CHECK_STATE_IN);
		prjPrdPaySchMQueryCondition.setAudStsCdList(audStsCdList);
		//审核通过  不通过
		List<String> audStsCd1List = new ArrayList<>();
		audStsCd1List.add(FlowConstant.FLOW_CHECK_STATE_PASS);
		audStsCd1List.add(FlowConstant.FLOW_CHECK_STATE_NO_PASS);
		prjPrdPaySchMQueryCondition.setAudStsCd1List(audStsCd1List);
        prjPrdPaySchMQueryCondition.setPaySchTypCd(PrjPrdPaySchMConstant.PAY_SCH_TYP_CD_WS);
		List<PrjPrdPaySchMDTO> prjPrdPaySchMDTOList = this.prjPrdPaySchMApiService.searchPrjPrdPaySchMForInvoiceList(prjPrdPaySchMQueryCondition);
        BaseLogUtils.info(logger, "searchApplyList", "查询开票申请时所能开发票的列表数据!prjPrdPaySchMDTOList" + JSON.toJSONString(prjPrdPaySchMDTOList));

        //收入显示
		String capFlowA = PropertiesCacheUtils.getProperty(fl.constant.facade.framework.constant.DictionaryConstant.CODE_CAP_FLOW_CD_A);
		if(CollectionUtils.isNotEmpty(prjPrdPaySchMDTOList)){
			
			PrjBillApplyRecDTO temp = null;
			for (PrjPrdPaySchMDTO prjPrdPaySchMDTO : prjPrdPaySchMDTOList) {
				temp = new PrjBillApplyRecDTO();
				temp.setFeeTypCd(DictionaryConstant.CODE_PRJ_QUAT_FEE_TYP_CD_S06);
				temp.setFeeTypCdNm(feeTypCdMap.get(DictionaryConstant.CODE_PRJ_QUAT_FEE_TYP_CD_S06));
				temp.setPaySchNo(prjPrdPaySchMDTO.getPaySchNo());
				temp.setPaySchId(prjPrdPaySchMDTO.getId());
				temp.setPayPd(-1);//租赁物总加默认为-1期次
				temp.setPaySchDtlId(0L);//租赁物总额支付表明细ID默认为0
				Long tot = null == prjPrdPaySchMDTO.getTotLsItmAmt()?0L:prjPrdPaySchMDTO.getTotLsItmAmt().longValue();
				temp.setFeeAmt(tot);
				temp.setPaidUpAmt(tot);
				temp.setCapFlowNm(capFlowCdMap.get(capFlowA));
				temp.setPrjId(prjPrdPaySchMDTO.getPrjId());
				list.add(temp);
			}
		}
		
		//==============================1结束===============================================
		
		//======================2、查询租金罚息数据: 支付表ID + 支付表明细ID + 期次查询逾期   -并且这个要过滤是否在申请表中已经存在=============
		PrjBillApplyRecQueryCondition prjBillApplyRecQueryCondition = new PrjBillApplyRecQueryCondition();
		prjBillApplyRecQueryCondition.setCstId(condition.getCstId());
		prjBillApplyRecQueryCondition.setPrjIdList(prjIdList);
		List<String> feeTypCdList = new ArrayList<>();
		feeTypCdList.add(DictionaryConstant.CODE_PRJ_QUAT_FEE_TYP_CD_S02);
		feeTypCdList.add(DictionaryConstant.CODE_PRJ_QUAT_FEE_TYP_CD_S03);
		prjBillApplyRecQueryCondition.setFeeTypCdList(feeTypCdList);
		prjBillApplyRecQueryCondition.setSysCd(CurrentThreadContext.getCurrentSysCd());
		prjBillApplyRecQueryCondition.setOrgCd(CurrentThreadContext.getCurrentOrgCd());
		if(StringUtils.isNotEmpty(paySchMId)){
			prjBillApplyRecQueryCondition.setPaySchMId(paySchMId);
		}
		
		List<PrjBillApplyRecDTO> defaultInterestList = this.custInvoiceApiService.searchListForInvoiceDefaultInterest(prjBillApplyRecQueryCondition);
		CapOverdueCompleteQC capOverdueCompleteQC = null;
		if(CollectionUtils.isNotEmpty(defaultInterestList)){
			capOverdueCompleteQC = new CapOverdueCompleteQC();
			capOverdueCompleteQC.setVfTypCd(CapitalConstant.CODE_VF_TYP_CD_1);
			capOverdueCompleteQC.setVfStsCd(CapitalConstant.CODE_CAP_FUND_STS_CD_2);
			List<String> feeTypCdList1 = new ArrayList<>();
			//feeTypCdList1.add(DictionaryConstant.CODE_PRJ_QUAT_FEE_TYP_CD_S02);//查询罚息只需要S05 所以这个查询去掉  20170803
			//feeTypCdList1.add(DictionaryConstant.CODE_PRJ_QUAT_FEE_TYP_CD_S03);//查询罚息只需要S05 所以这个查询去掉  20170803
			feeTypCdList1.add(DictionaryConstant.CODE_PRJ_QUAT_FEE_TYP_CD_S05);
			capOverdueCompleteQC.setFeeTypCdList(feeTypCdList1);
			//未提交 、审核中
			List<String> audStsCdList1 = new ArrayList<>();
			audStsCdList1.add(FlowConstant.FLOW_CHECK_STATE_NON);
			audStsCdList1.add(FlowConstant.FLOW_CHECK_STATE_IN);
			capOverdueCompleteQC.setAudStsCdList(audStsCdList1);
			capOverdueCompleteQC.setAudStsCdPass(FlowConstant.FLOW_CHECK_STATE_PASS);
			capOverdueCompleteQC.setFeeTypCdS05(DictionaryConstant.CODE_PRJ_QUAT_FEE_TYP_CD_S05);
			capOverdueCompleteQC.setBillStsCd(DictionaryConstant.CODE_PRJ_BILL_STS_CD_1);
			List<Long> paySchIdList = new ArrayList<>();
			for (PrjBillApplyRecDTO prjBillApplyRecDTO : defaultInterestList) {
				Integer payPd = prjBillApplyRecDTO.getPayPd();
				if(null == payPd || payPd.intValue() <= 0) continue;
				Long paySchId = prjBillApplyRecDTO.getPaySchId();
				if(StringUtils.isEmpty(paySchId)){
					continue;
				}
				paySchIdList.add(paySchId);
			}
			CollectionUtils.removeDuplicate(paySchIdList);
			capOverdueCompleteQC.setPaySchIdList(paySchIdList);
		}
		
		//通过2中结果获取罚息记录---查询核销表：1、 核销类型：已核销  2、  核销状态集合：已分解    3、费用类型代码：本金、利息  4、  支付表ID 5、是否删除：否
		if(null != capOverdueCompleteQC){
			List<CapFundVfDtlDTO> capFundVfDtlVOList = this.capOverdueInfoApiService.searchFundCompleteListForBill(capOverdueCompleteQC);
			if(CollectionUtils.isNotEmpty(capFundVfDtlVOList)){
				//把数据封装到list中
				PrjBillApplyRecDTO temp = null;
				for (CapFundVfDtlDTO capFundVfDtlDTO : capFundVfDtlVOList) {
					String feeTypCd = capFundVfDtlDTO.getFeeTypCd();
					Long payPdT = capFundVfDtlDTO.getPayPd();
					temp = new PrjBillApplyRecDTO();
					temp.setFeeTypCd(DictionaryConstant.CODE_PRJ_QUAT_FEE_TYP_CD_S05);
					temp.setFeeTypCdNm("第" + payPdT + "期" + feeTypCdMap.get(feeTypCd) + feeTypCdMap.get(DictionaryConstant.CODE_PRJ_QUAT_FEE_TYP_CD_S05));
					temp.setPaySchNo(capFundVfDtlDTO.getPaySchNo());
					temp.setPaySchId(capFundVfDtlDTO.getPaySchId());
					temp.setPaySchDtlId(0L);//支付表明细ID默认为0
					Long tot = null == capFundVfDtlDTO.getVfAmt()?0L:capFundVfDtlDTO.getVfAmt().longValue();
					temp.setFeeAmt(tot);
					temp.setPaidUpAmt(tot);
					if(null != payPdT){
						temp.setPayPd(payPdT.intValue());
					}
					temp.setOdId(capFundVfDtlDTO.getId());
					temp.setCapFlowNm(capFlowCdMap.get(capFlowA));
					temp.setPrjId(capFundVfDtlDTO.getPrjId());
					list.add(temp);
				}
			}
		}
		//====================================2结束===============================================
		//要对list中进行排序 prjPPSM.PAY_SCH_NO ASC , prjPPSD.PAY_PD ASC, prjPPSD.FEE_TYP_CD ASC
		if(CollectionUtils.isNotEmpty(list)){
			List<Long> projectIdList = new ArrayList<Long>();//项目IDList
			for (PrjBillApplyRecDTO prjBillApplyRecDTO : list) {
				projectIdList.add(prjBillApplyRecDTO.getPrjId());
				String feeTypCd = prjBillApplyRecDTO.getFeeTypCd();
				if(StringUtils.isNotEmpty(feeTypCd)){
					String feeTypValue = feeTypMap.get(feeTypCd);
					String feeTypText = billTypeMap.get(feeTypValue);
					prjBillApplyRecDTO.setBillTypCdDefText(feeTypText);
					prjBillApplyRecDTO.setBillTypCdDefValue(feeTypValue);
				}
			}
			BaseLogUtils.info(logger, "searchApplyList", "A项目ID:" + JSON.toJSONString(projectIdList));
			PrjBscInfoQueryCondition qc = new PrjBscInfoQueryCondition();
			CollectionUtils.removeDuplicate(projectIdList);
			qc.setIdList(projectIdList);
			List<PrjBscInfoDTO> searchList = projectApiService.searchList(qc, CurrentThreadContext.getCurrentSysCd(), CurrentThreadContext.getCurrentOrgCd());
			Map<Long,String> temp = new HashMap<>();
			if(CollectionUtils.isNotEmpty(searchList)){
				for (PrjBscInfoDTO prjBscInfoDTO : searchList) {
					temp.put(prjBscInfoDTO.getId(), prjBscInfoDTO.getBizTypCd());
				}
			}
			if(CollectionUtils.isMapNotEmpty(temp)){
				Map<String, String> bizTypCdMap = this.sysDictionaryApiService.searchGroupToMap(CurrentThreadContext.getCurrentSysCd(),
						PropertiesCacheUtils.getProperty(SystemConstant.FL_ORG_CD), DictionaryConstant.CODE_PRJ_BIZ_TYP_CD);
				for (PrjBillApplyRecDTO prjBillApplyRecDTO : list) {
					if(temp.containsKey(prjBillApplyRecDTO.getPrjId())){
						String bizTypCd = temp.get(prjBillApplyRecDTO.getPrjId());
						prjBillApplyRecDTO.setBizTypCdNm(bizTypCdMap.get(bizTypCd));
					}
				}
			}
		}
		
		Collections.sort(list);
		return PrjBillApplyRecVOTransform.toVOList(list);
	}

	@Override
	public boolean addBillBscInfo(PrjBillApplyVO entity) throws BaseException {
		return this.custInvoiceApiService.addBillBscInfo(PrjBillApplyVOTransform.toDTO(entity));
	}

	@Override
	public boolean modifyStopUsedZF(Long id, String billStsCd) throws BaseException {
		if(StringUtils.isEmpty(id)){
			BaseLogUtils.info(logger, "modify", "主键不能为空!", CurrentThreadContext.getCurrentUserName());
		}
		
		if(StringUtils.isEmpty(billStsCd)){
			BaseLogUtils.info(logger, "modify", "票据状态不能为空!", CurrentThreadContext.getCurrentUserName());
		}
		
		return this.custInvoiceApiService.modifyStopUsedZF(id, billStsCd);
	}
	
	@Override
	public DataResultDTO addFlowStart(FlowStartParamsDTO flowStartParamsDTO, PrjBillApplyVO entity) throws BaseException {
		if(StringUtils.isEmpty(flowStartParamsDTO.getCrtUsrId())){
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "创建人ID必须要存在!");
		}
		if(null == entity){
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "业务数据对象不能为空!");
		}
		return this.custInvoiceApiService.addFlowStart(flowStartParamsDTO, PrjBillApplyVOTransform.toDTO(entity));
	}

	@Override
	public DataResultDTO addFlowStartNormal(FlowStartParamsDTO flowStartParamsDTO) throws BaseException {
		if(StringUtils.isEmpty(flowStartParamsDTO.getCrtUsrId())){
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "创建人ID必须要存在!");
		}
		return this.custInvoiceApiService.addFlowStartNormal(flowStartParamsDTO);
	}

    /**
     *
     * @param operFlag（1 开具 2 打印 3 作废 4 冲红 （1 3 4获取税控钥匙的报文））
     * @return
     * @throws BaseException
     */
    @Override
    public JSONArray getXml(String operFlag, Long bscInfoId) throws BaseException {
        JSONArray xmls = new JSONArray();
        HashMap<String, String> params = new LinkedHashMap<>();
        String xml;
        if ("2".equals(operFlag)) {
            PrjBillBscInfoVO prjBillBscInfoVO = PrjBillBscInfoVOTransform.toVO(this.custInvoiceApiService.getPrjBillBscInfoById(bscInfoId));
            if (null == prjBillBscInfoVO) {
                throw new BaseException("无法查询票据基础信息");
            }
            // 打印
            // 参数设置
            params.put("servletip", PropertiesCacheUtils.getProperty("invoice.invoice.properties.servletip"));
            params.put("servletport", PropertiesCacheUtils.getProperty("invoice.invoice.properties.servletport"));
            params.put("keypwd", PropertiesCacheUtils.getProperty("invoice.invoice.properties.keypwd"));
            xml = XmlUtils.createXml(Charset.forName("GBK"), "20001", "参数设置", params);
            xmls.add(xml);
            params.clear();
            // 页边距设置
            if (PrjBillApplyConstant.BILL_TYP_CD_1.equals(prjBillBscInfoVO.getBillTypCd())) {
                params.put("fplxdm", "004");
            } else if (PrjBillApplyConstant.BILL_TYP_CD_2.equals(prjBillBscInfoVO.getBillTypCd())) {
                params.put("fplxdm", "007");
            }
            SysDictionaryDTO dic = sysDictionaryApiService.getCode(CurrentThreadContext.getCurrentSysCd(), CurrentThreadContext.getCurrentOrgCd(), PrjBillApplyConstant.PRINT_CONFIG, PrjBillApplyConstant.PRINT_CONFIG_1);
            if (null != dic) {
                params.put("top", dic.getCodeNm());
            }
            dic = sysDictionaryApiService.getCode(CurrentThreadContext.getCurrentSysCd(), CurrentThreadContext.getCurrentOrgCd(), PrjBillApplyConstant.PRINT_CONFIG, PrjBillApplyConstant.PRINT_CONFIG_2);
            if (null != dic) {
                params.put("left", dic.getCodeNm());
            }
            xml = XmlUtils.createXml(Charset.forName("GBK"), "20003", "页边距设置", params);
            xmls.add(xml);
            params.clear();
            // 发票打印
            params.put("kpzdbs", prjBillBscInfoVO.getTerminalMark());
            if (PrjBillApplyConstant.BILL_TYP_CD_1.equals(prjBillBscInfoVO.getBillTypCd())) {
                params.put("fplxdm", "004");
            } else if (PrjBillApplyConstant.BILL_TYP_CD_2.equals(prjBillBscInfoVO.getBillTypCd())) {
                params.put("fplxdm", "007");
            }
            params.put("fpdm", prjBillBscInfoVO.getInvoiceCode());
            params.put("fphm", prjBillBscInfoVO.getBillNo());
            params.put("dylx", "0");
            params.put("dyfs", "0");
            xml = XmlUtils.createXml(Charset.forName("GBK"), "20004", "发票打印", params);
            xmls.add(xml);
            params.clear();
        } else if ("1".equals(operFlag) || "3".equals(operFlag) || "4".equals(operFlag)) {
            // 开具 || 作废 || 冲红
            params.put("keypwd", PropertiesCacheUtils.getProperty("invoice.invoice.properties.keypwd"));
            xml = XmlUtils.createXml(Charset.forName("GBK"), "20002", "税控钥匙信息查询", params);
            xmls.add(xml);
        }
        return xmls;
    }

    @Override
    public List<KeyValueVO> queryPrjByCstId(Long cstId) throws BaseException{
        if (cstId == null) {
            throw new BaseException("请求参数客户ID不能为空！");
        }
		return this.invoiceApiService.searchContNoForInvoice(cstId);
	}

    @Override
    public List<KeyValueVO> querySupportFeeTyp(String billWayCd) throws BaseException {
        return this.invoiceApiService.querySupportFeeTyp(billWayCd);
    }

    @Override
    public List<ValidInvoiceDataDTO> searchValidInvoiceList(SearchValidInvoiceQueryCondition condition) throws BaseException {
        return this.invoiceApiService.searchValidInvoiceList(condition);
    }

    @Override
    public DataResultDTO executeDoInvalidInvoicePaper(PrjBillBscInfoDTO request) throws BaseException {
        return this.invoiceApiService.executeDoInvalidInvoicePaper(request);
    }

    @Override
    public DataResultDTO executeDoInvoiceElectron(InvoiceApplyReqDTO reqDTO) throws BaseException {
        return this.invoiceApiService.executeDoInvoiceElectron(reqDTO);
    }

    @Override
    public DataResultDTO executeDoInvoicePaper(InvoiceApplyReqDTO reqDTO) throws BaseException {
        return this.invoiceApiService.executeDoInvoicePaper(reqDTO);
    }

    @Override
    public String getDownloadUrl(Long billId) throws BaseException {
        return this.invoiceApiService.getDownloadUrl(billId);
    }

    @Override
    public void executePush(PrjBillApplyVO request) throws BaseException {
        this.invoiceApiService.executePush(PrjBillApplyVOTransform.toDTO(request));
    }

    @Override
    public void checkInvoiceFeeIfPresent(List<Long> paySchDtlIdList) throws BaseException {
        this.invoiceApiService.checkInvoiceFeeIfPresent(paySchDtlIdList);
    }
}
